/*
 * 作者: Franz Pucher
 */

#ifndef ADAFRUIT_MOTOR_CONTROLLER_H
#define ADAFRUIT_MOTOR_CONTROLLER_H

// 这个示例中的特殊代码是使用了Arduino的Wire库。
// Wire是一个I2C库，可以简化对I2C总线的读写操作。
#include <Wire.h>
#include <Adafruit_MotorShield.h>

#include "diffbot_base_config.h"

#include <motor_controller_interface.h>

namespace diffbot {

    /** \brief Adafruit_MotorShield的MotorControllerIntf实现
     * 
     * 实现了MotorControllerIntf中的抽象方法setSpeed
     * 
     * 该类使用了adafruit-stepper-dc-motor-featherwing库。
     * 
     * \note 更多细节请参见
     * https://learn.adafruit.com/adafruit-stepper-dc-motor-featherwing/library-reference
     */
    class AdafruitMotorController : public MotorControllerIntf<Adafruit_MotorShield>
    {
        public:
            /** \brief 构造一个用于单个电机的\ref AdafruitMotorController
             * 
             * 指定要控制的电机\p motor_num（对于diffbot使用3或4）。
             * 指定要使用的i2c地址。默认地址是0x60，但可以通过焊接PCB底部的不同地址开关来更改。
             * 
             * \param motor_num 要控制的电机编号（1, 2, 3, 4之一）。Diffbot使用电机3和4。
             * \param addr 用于与电机驱动器通信的i2c地址。
             */
            AdafruitMotorController(uint8_t motor_num, uint8_t addr=0x60);

            /** \brief 初始化与电机驱动器的通信
             * 
             * 必须在setup()中调用以初始化电机驱动器。
             * 可以使用一个可选的频率参数来指定不同于默认最大值的频率：1.6KHz PWM频率。
             */
            void begin(uint16_t freq = 1600);

            /** \brief 设置电机\ref pMotor_的速度。
             * 
             * setSpeed接口方法的具体实现，用于控制连接到Adafruit_MotorShield的单个电机。
             * 输入参数\p value的范围是-255到255。
             * 在此方法中，值被映射到0到255之间，并使用符号来设置方向。
             * 正的\p value使电机向前旋转。
             * 负的\p value使电机向后旋转，零值停止电机（释放电流）。
             * 
             * \note 更多细节请参见
             * https://learn.adafruit.com/adafruit-stepper-dc-motor-featherwing/library-reference
             * 
             * \param value 正或负值，用于设置电机的方向和速度。
             */
            void setSpeed(int value) override;
            

        private:
            // 指向由此电机控制器控制的电机的指针。
            Adafruit_DCMotor *pMotor_;
    };

}

#endif // ADAFRUIT_MOTOR_CONTROLLER_H